<?php

namespace App\Sdk\Pay;

use Omnipay\Omnipay;

class Alipay
{
    private $gateway;
    private $channel;

    /**
     * Alipay constructor.
     * @param string $sitecode
     * @param string $type
     * @throws \Exception
     */
    public function __construct($channel = '')
    {
        $this->channel = $channel;
        switch ($channel) {
            case 'app':
                $this->gateway = Omnipay::create('Alipay_LegacyApp');
                $this->gateway->setSellerId(config('meice.alipay.partner'));
                break;
            case 'm':
                $this->gateway = Omnipay::create('Alipay_LegacyWap');
                $this->gateway->setSellerId(config('meice.alipay.partner'));
                break;
            case 'web':
                $this->gateway = Omnipay::create('Alipay_LegacyExpress');
                $this->gateway->setSellerEmail(config('meice.alipay.seller_id'));
                break;
            case 'refund':
                $this->gateway = Omnipay::create('Alipay_LegacyApp');
                $this->gateway->setSellerId(config('meice.alipay.seller_id'));
                break;
            default:
                throw new \Exception('类型传值错误，只能传入app、m、web');
                break;
        }

        $this->gateway->setInputCharset(config('meice.alipay.input_charset'));
        $this->gateway->setSignType(config('meice.alipay.sign_type')); //RSA/RSA2
        $this->gateway->setPartner(config('meice.alipay.partner'));
        $this->gateway->setPrivateKey(config('meice.alipay.private_key'));
        $this->gateway->setAlipaySdk('alipay_sdk');
    }

    /**
     * 根据相关信息创建支付交易,如果网页的返回跳转链接，app的返回sdk需要的orderString
     * @param array $data
     * @return bool
     */
    public function createTrade($data, $notifyUrl, $returnUrl = '')
    {
        if (empty($data) || empty($notifyUrl)) {
            return false;
        }

        $this->gateway->setReturnUrl($returnUrl);
        $this->gateway->setNotifyUrl($notifyUrl);

        try {
            $this->gateway->setAlipayPublicKey(config('meice.alipay.public_key'));
            $this->gateway->setKey(config('meice.alipay.key'));
            $response = $this->gateway->purchase($data)->send();
            if ($this->channel == 'app') {
                return $response->getOrderString();
            } else {
                return $response->getRedirectUrl();
            }
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 支付宝的支付结果回调处理
     * @param $tradeData
     * @return bool
     */
    public function completePurchase($tradeData)
    {
        $this->gateway->setAlipayPublicKey(config('meice.alipay.public_key'));
        $this->gateway->setKey(config('meice.alipay.key'));

        try {
            unset($tradeData['net']);
            $request = $this->gateway->completePurchase();
            $request->setParams($tradeData);
            $response = $request->send();
            if ($response->isPaid()) {
                return $response->getData();
            } else {
                return $response->getData();
            }
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 无密退款
     * @param string $alipay_trade_no
     * @param int $amount
     * @return bool|mixed
     */
    public function refundNoPwd($alipay_trade_no = '', $amount = 0)
    {
        if ($alipay_trade_no == '') {
            return false;
        }

        try {
            $data = [
                'refund_date'  => date('Y-m-d H:i:s'),
                'batch_no'     => date('Ymd') . $this->random(12, 1),
                'batch_num'    => 1,//退款笔数与refund_items数组中保持一致
                'refund_items' => [
                    [
                        'trade_no' => $alipay_trade_no,
                        'amount'   => $amount,
                        'reason'   => '取消',
                    ],
                ],
            ];
            $this->gateway->setAlipayPublicKey(config('meice.alipay.public_key'));
            $response = $this->gateway->refundNoPwd($data)->send();
            if ($response->isSuccessful()) {
                return true;
            } else {
                $data = $response->getData();

                return $data['is_success'] . '->' . $data['error'];
            }
        } catch (\Exception $e) {
            return $e->getMessage();
        }
    }

    /**
     * 生成随机数
     *
     * @param int $length  随机数长度
     * @param int $numeric 是否只生成数字
     *
     * @return string
     */
    function random($length, $numeric = 0)
    {
        $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
        $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
        $hash = '';
        $max = strlen($seed) - 1;
        for ($i = 0; $i < $length; $i++) {
            $hash .= $seed{mt_rand(0, $max)};
        }

        return $hash;
    }
}